<?php


/**
 *	@name ISODuration
 *  @copyright Package SOAP from PEAR.php.net
 *	@copyright SMART - ULg (www.smart.ulg.ac.be)		
 *
**/


/**
 * Class ISODuration : 
 * description
 * 
 * $Rev$ 
 * $LastChangedRevision$
 * $LastChangedBy$
 * $LastChangedDate$
 * $HeadURL$
 *
 * @name ProjectsListBroker
 * @package webservices/broker
 * @author : JPh HUMBLET
 * @copyright : SMART - ULg (www.smart.ulg.ac.be)
 * @category : ExAMS::Core
 *
**/

class ISODuration
{
	public static $ereg_duration = '(-)?P([0-9]+Y)?([0-9]+M)?([0-9]+D)?T?([0-9]+H)?([0-9]+M)?([0-9]+S)?';
	
 	// format PnYnMnDTnHnMnS
    function unix_to_duration($seconds) {
    	return ISODuration::getduration($seconds);
    }


    function mod($a, $b, &$d, &$r) {
        $d = floor( $a / $b );
        $r = $a % $b;
    }

	
    function getduration($seconds) {
        $neg = '';
        if ($seconds < 0) {
            $neg = '-';
            $seconds = $seconds * -1;
        }
        $_mi = 60;
        $_h = $_mi * 60;
        $_d = $_h * 24;
        // XXX how do we properly handle month and year values?
        $_m = $_d * 30;
        $_y = $_d * 365;

        ISODuration::mod($seconds, $_y, $y, $seconds);
        ISODuration::mod($seconds, $_m, $m, $seconds);
        ISODuration::mod($seconds, $_d, $d, $seconds);
        ISODuration::mod($seconds, $_h, $h, $seconds);
        ISODuration::mod($seconds, $_mi, $mi, $s);

        $duration = $neg.'P';
        if ($y) $duration .= $y.'Y';
        if ($m) $duration .= $m.'M';
        if ($d) $duration .= $d.'D';
        if ($h || $mi || $s) $duration .='T';
        if ($h) $duration .= $h.'H';
        if ($mi) $duration .= $mi.'M';
        if ($s) $duration .= $s.'S';
        if ($duration == 'P' || $duration == '-P') $duration = 'PT0S';
        return $duration;
    }

    function mkduration($n, $Y, $Mo, $D, $H, $Mi, $S) {
        $_mi = 60;
        $_h = $_mi * 60;
        $_d = $_h * 24;
        // XXX how do we properly handle month and year values?
        $_m = $_d * 30;
        $_y = $_d * 365;
        $sec = $Y * $_y + $Mo * $_m + $D * $_d + $H * $_h + $Mi * $_mi + $S;
        if ($n == '-') $sec = $sec * -1;
        return $sec;
    }



    function duration_to_unix($duration) {
        if (ereg(ISODuration::$ereg_duration,$duration,$regs)) {
            return ISODuration::mkduration($regs[1], $regs[2], $regs[3], $regs[4], $regs[5], $regs[6], $regs[7]);
        }
        return FALSE;
    }

	/**
	 * duration_to_string
	 * undocumented function
	 *
	 * @return void
	 * @author jph (jp.humblet@ulg.ac.be)
	**/
	public function duration_to_string($duration) {
		$r = ISODuration::duration_to_unix($duration);
		if ($r) {
			return round( ($r/3600), 1). "h"; 
		}
	}
	

    static function is_duration($duration) {
        return ereg(ISODuration::$ereg_duration,$duration,$regs);
    }


    function _test($time) {
        if (ISODuration::is_duration($time)) {
            $t = ISODuration::duration_to_unix($time);
            echo "Duration: $time is ".$t." seconds\n";
        } else {
            $t = ISODuration::unix_to_duration($time);
            echo "Seconds: $time is ".$t." duration\n";
        }
        return $t;
    }



    static function add($d1, $d2) {
        $s1 = ISODuration::duration_to_unix($d1);
        $s2 = ISODuration::duration_to_unix($d2);
        return ISODuration::unix_to_duration($s1 + $s2);
    }



    static function subtract($d1, $d2) {
        $s1 = ISODuration::duration_to_unix($d1);
        $s2 = ISODuration::duration_to_unix($d2);
        return ISODuration::unix_to_duration($s1 - $s2);
    }

}

?>